iT邦幫忙

2021 iThome 鐵人賽

DAY 13
0

權責劃分

VoK整合登入

當使用者登入系統後,無論是因為使用者權責亦或是為了系統安全,通常會建立適當的安全機制,除了密碼加密外,還有角色與權責分配,比如什麼樣的角色(role)分配什麼樣的功能。本節將帶大家透過 VoK-Security 建立系統權責劃分。

為系統建立適合的角色

在本範例學生成績管理系統裡,功能/角色分配如下 :

  • 角色 : administrator, teacher, student
  • 新增/修改/刪除學生 - administrator
  • 查詢學生 : 全部
  • 新增/修改/刪除成績 - teacher
  • 查詢成績 - 一般而言,學生僅能查到自己的成績,但在本例中,學生為自動顏生,故分配只要具有 teacher, student 角色皆能查詢成績。

請打開 LoginServices.kt

修改 User()

data class User(
    override var id: Long? = null,
    var username: String = "",
    override var hashedPassword: String = "",
    var roles: String = ""
) : KEntity<Long>, HasPassword {
    companion object : Dao<User, Long>(User::class.java) {
        fun findByUsername(username: String): User? = findOneBy("username = :username") { query ->
            query.bind("username", username)
        }
    }
}

VoK Secruity 提供hash加密password,無需自行轉換,只要實作 HasPassword,並複寫 hashedPasswordHasPassword 將會於設定密碼時,自動將加密後的 password 回寫 hashedPassword

建立使用者資料表

在 web/src/main/resources/db/migration 下開新檔案 V03__CreateUser.sql

create table user (
  id bigint auto_increment primary key not null,
  username varchar(100) not null,
  hashedPassword varchar(200) not null,
  roles varchar(400) not null
);
create unique index on user(username);

除了primary key外,username 為唯一值,且將會根據username查詢,所以建立唯一值索引 (unique index)

檢查登入帳密

修改login()

    fun login(username: String, password: String): Boolean {
        //verify username and password
        val user = User.findByUsername(username) ?: return false
        if (!user.passwordMatches(password)) return false
        currentUser = user
        UI.getCurrent().page.reload()
        return true
    }

第三行,倘若無此使用者,回傳登入失敗 (false)
第四行,使用 HasPassword 提供的方法 passwordMatches() 檢查密碼

增加必要方法

    fun getCurrentUserRoles(): Set<String>{
        val roles: String = currentUser?.roles ?: return setOf()
        return roles.split(",").toSet()
    }

    fun isUserInRole(role: String): Boolean = getCurrentUserRoles().contains(role)

    fun isAdmin(): Boolean = isUserInRole("administrator")

第三行,一個使用者可具多重角色,各角色間以,分隔
第六行,檢查role是否存在

建立測試使用者資料

    User(username = "admin", roles = "admin").apply { setPassword("admin") }.save(false)
    User(username = "teacher", roles = "teacher").apply { setPassword("teacher") }.save(false)
    User(username = "student", roles = "student").apply { setPassword("student") }.save(false)

  • 使用 HasPassword 所提供的方法 setPassword() 設定密碼
  • .save(false) 表示儲存時不需檢查資料正確性。

上一篇
提供 REST API / 限定欄位 / 格式化LocalDate - day12
下一篇
VoK 系統功能權責劃分 ( II ) - day14
系列文
使用 Kotlin 快速開發 Web 程式 -- Vaadin30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言